/*    
    OpenMheg - A free MHEG-5 library
    Copyright (C) 2008 Dharmesh Malam

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

using System;
using System.Collections.Generic;
using System.Collections;
using System.Text;
using System.Drawing;
using Core.Model.Data.Variables;
using Core.Model.Data.Generics;
using Core.Model.Util;
using System.Collections.ObjectModel;
using Core.Model.Events;


namespace Core.Model
{
    public abstract class Visible : Presentable
    {
        #region  Exchanged attributes
        private Size originalBoxSize;

        public Size OriginalBoxSize
        {
            get { return originalBoxSize; }
            set { originalBoxSize = value; }
        }

        private Point originalBoxPosition;

        public Point OriginalBoxPosition
        {
            get { return originalBoxPosition; }
            set { originalBoxPosition = value; }
        }
        #endregion

        #region  Internal attributes
        private Size boxSize;

        public Size BoxSize
        {
            get { return boxSize; }
            set { boxSize = value; }
        }
        private Point boxPosition;

        public Point BoxPosition
        {
            get { return boxPosition; }
            set { boxPosition = value; }
        }

        public System.Drawing.Rectangle BoxArea
        {
            get { return new System.Drawing.Rectangle( boxPosition, boxSize ); }
        }

        #endregion

        #region  Implementation specific

        public delegate void RedrawAreasHandler ( params System.Drawing.Rectangle [] rs );
        public delegate void RedrawAreaHandler ( Point boxPosition, Size boxSize );
        public delegate void RedawHandler ();
        protected event RedrawAreasHandler redrawAreas;
        protected event RedrawAreaHandler redrawArea;
        protected event RedawHandler redraw;


        protected void OnRedrawAreas ( params System.Drawing.Rectangle [] rs )
        {
            //redrawAreas.BeginInvoke( rs, null, null );
            redrawAreas( rs );
        }
        protected void OnRedrawArea ( Point boxPosition, Size boxSize )
        {
            //redrawArea.BeginInvoke( boxPosition, boxSize, null, null );
            redrawArea( boxPosition , boxSize );
        }

        protected void OnRedraw ()
        {
            //redraw.BeginInvoke( null, null );
            redraw();
        }

        public override void InittInternalAttributes ()
        {
            base.InittInternalAttributes();

            boxSize = originalBoxSize;
            boxPosition = originalBoxPosition;

            redrawAreas += new RedrawAreasHandler( MHEGEngine.Instance.DisplayStack.RedrawAreas );
            redrawArea += new RedrawAreaHandler( MHEGEngine.Instance.DisplayStack.RedrawArea );
            redraw += new RedawHandler( MHEGEngine.Instance.DisplayStack.Redraw );
        }
        #endregion

        #region  Internal behaviours
        public override void Prepare ()
        {
            MHEGEngine.Instance.DisplayStack.Add( this );
            base.Prepare();
        }

        public override void Destroy ()
        {
            MHEGEngine.Instance.DisplayStack.Remove( this );
            base.Destroy();
        }

        public override void Activate ()
        {
            if ( !RunningStatus )
            {
                base.Activate();
                OnRedrawArea( boxPosition, boxSize );
                RunningStatus = true;
                MHEGEngine.Instance.Handle( new IsRunning( this ) );
            }
        }

        public override void Deactivate ()
        {
            if ( RunningStatus )
            {
                base.Deactivate();
                OnRedrawArea( boxPosition, boxSize );
            }
        }
        #endregion

        #region  Internal behaviours
        public void SetPosition ( int x, int y )
        {
            System.Drawing.Rectangle rectangle = new System.Drawing.Rectangle( boxPosition, boxSize );

            boxPosition.X = x;
            boxPosition.Y = y;

            if (RunningStatus)
                OnRedrawAreas( new System.Drawing.Rectangle( boxPosition, boxSize ), rectangle );

        }

        public void SetSize ( int width, int height )
        {
            Size size =new Size( Math.Max( width, boxSize.Width ),
                            Math.Max( height, boxSize.Width ) );

            boxSize.Width = width;
            boxSize.Height = height;

            if ( RunningStatus )
                OnRedrawArea( boxPosition, size );
        }

        public void ResetPosition ()
        {
            System.Drawing.Rectangle rectangle = new System.Drawing.Rectangle( boxPosition, boxSize );

            boxPosition = originalBoxPosition;
            boxSize = originalBoxSize;

            
            OnRedrawAreas( new System.Drawing.Rectangle( boxPosition, boxSize ), rectangle );

        }
        #endregion

        #region  Actions
        public virtual void SetPosition ( GenericInteger newX, GenericInteger newY )
        {
            SetPosition( newX.Value, newY.Value );

        }

        public virtual void GetPosition ( IntegerVariable xPos, IntegerVariable yPos )
        {
            xPos.Value =  boxPosition.X;
            yPos.Value = boxPosition.Y;
        }

        public virtual void SetBoxSize ( GenericInteger width, GenericInteger height )
        {
            SetSize( width.Value, height.Value );

        }

        public virtual void GetBoxSize ( IntegerVariable width, IntegerVariable height )
        {
            width.Value = boxSize.Width;
            height.Value = boxSize.Height;
        }

        public void BringToFront ()
        {
            MHEGEngine.Instance.DisplayStack.BringToFront( this );
        }

        public void SendToBack ()
        {
            MHEGEngine.Instance.DisplayStack.SendToBack( this );
        }

        public void PutBefore ( Visible reference )
        {
            MHEGEngine.Instance.DisplayStack.PutBefore( this, reference );
        }

        public void PutBehind ( Visible reference )
        {
            MHEGEngine.Instance.DisplayStack.PutBehind( this, reference );
        }
        #endregion

        public override void SetData ( GenericOctetString newContent )
        {
           // System.Drawing.Rectangle rectangle = new System.Drawing.Rectangle( boxPosition, boxSize );

            base.SetData( newContent );
            

            if ( RunningStatus )
                OnRedrawAreas( new System.Drawing.Rectangle( boxPosition, boxSize ));//, rectangle );

        }

        public override void SetData ( GenericContentRef newContent )
        {
            System.Drawing.Rectangle rectangle = new System.Drawing.Rectangle( boxPosition, boxSize );
            base.SetData( newContent );

            if ( RunningStatus )
                OnRedrawAreas( new System.Drawing.Rectangle( boxPosition, boxSize ), rectangle );
        }


    }
}